package org.liaohailong.victor;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;

/**
 * Author: liaohailong
 * Date: 2022/2/11
 * Time: 15:08
 * Description:
 **/
public class MathStudy {

    // 快乐数
    public boolean isHappy(int n) {
        return _isHappy(n, new HashSet<>());
    }

    private boolean _isHappy(int n, HashSet<Integer> visitor) {
        if (visitor.contains(n)) return false;
        int origin = n;
        int count = 0;
        while (n > 0) {
            int val = n % 10;
            count += (val * val);
            n /= 10;
        }
        if (count == 1) return true;
        else visitor.add(origin);
        return _isHappy(count, visitor);
    }


    // 阶乘后的零
    public int trailingZeroes(int n) {
        // 计算n以内能分解出几个5，最终有几个5就有几个0
        int count = 0;
        while (n >= 5) {
            //每次得出该次的前缀表示该次的次数。
            count += n / 5;
            n /= 5;
        }
        return count;
    }

    // ZY  =  26*26 + 24
    // Excel表列序号
    public int titleToNumber(String columnTitle) {
        int cnt = 0;
        for (int i = 0; i < columnTitle.length(); i++) {
            cnt = cnt * 26;
            cnt += columnTitle.charAt(i) - 'A';
        }
        return cnt;
    }

    public double myPow(double x, int n) {
        double res = 1.0;
        for (int i = n; i != 0; i /= 2) {
            if (i % 2 != 0) {
                res *= x;
            }
            x *= x;
        }
        return n < 0 ? 1 / res : res;
    }

    // x 的平方根
    public int mySqrt(int x) {
        int low = 0;
        int high = x;

        while (low < high) {
            long mid = low + (high - low) / 2;
            long pow = mid * mid;
            if (pow < x) {
                low = (int) (mid + 1);
            } else if (pow > x) {
                high = (int) (mid - 1);
            } else return (int) mid;
        }

        return low * low <= x ? low : low - 1;
    }

    // 两数相除
    public int divide(int dividend, int divisor) {
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        }
        return dividend / divisor;
    }

    // 分数到小数
    public String fractionToDecimal(int numerator, int denominator) {
        StringBuilder sbd = new StringBuilder();
        if ((numerator ^ denominator) < 0 && numerator != 0) {
            sbd.insert(0, "-");
        }
        long num = numerator > 0 ? numerator : -(long)numerator;
        long den = denominator > 0 ? denominator : -(long)denominator;
        Long a = num / den;
        long b = num % den;
        sbd.append(a).append('.');
        if (b == 0) {
            return sbd.toString().substring(0,sbd.length()-1);
        }
        HashMap<Long,Integer> map = new HashMap<>();
        while (b != 0 && !map.containsKey(b)) {
            map.put(b,sbd.length());
            b *= 10;
            a = b / den;
            b = b % den;
            sbd.append(a);
        }
        if (b != 0) {
            sbd.insert(map.get(b),"(");
            sbd.append(")");
        }
        return sbd.toString();
    }
}
